Sequential by default
|
suspend fun doSomethingUsefulOne(): Int {
delay(1000L) // pretend we are doing something useful here
return 13
}
suspend fun doSomethingUsefulTwo(): Int {
delay(1000L) // pretend we are doing something useful here, too
return 29
}
|
suspend func doSomethingUsefulOne() -> Int {
delay(1000L) // pretend we are doing something useful here
return 13
}
suspend func doSomethingUsefulTwo() -> Int {
delay(1000L) // pretend we are doing something useful here, too
return 29
}
|
val time = measureTimeMillis {
val one = doSomethingUsefulOne()
val two = doSomethingUsefulTwo()
println("The answer is ${one + two}")
}
println("Completed in $time ms")
|
let time = measureTimeMillis {
let one = doSomethingUsefulOne()
let two = doSomethingUsefulTwo()
print("The answer is ${one + two}")
}
print("Completed in $time ms")
|
Concurrent using async
|
val time = measureTimeMillis {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
|
let time = measureTimeMillis {
let one = async { doSomethingUsefulOne() }
let two = async { doSomethingUsefulTwo() }
print("The answer is ${one.await() + two.await()}")
}
print("Completed in $time ms")
|
Lazily started async
|
val time = measureTimeMillis {
val one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
val two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
// some computation
one.start() // start the first one
two.start() // start the second one
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
|
let time = measureTimeMillis {
let one = async(start = CoroutineStart.LAZY) { doSomethingUsefulOne() }
let two = async(start = CoroutineStart.LAZY) { doSomethingUsefulTwo() }
// some computation
one.start() // start the first one
two.start() // start the second one
print("The answer is ${one.await() + two.await()}")
}
print("Completed in $time ms")
|
Async-style functions
|
// The result type of somethingUsefulOneAsync is Deferred<Int>
fun somethingUsefulOneAsync() = GlobalScope.async {
doSomethingUsefulOne()
}
// The result type of somethingUsefulTwoAsync is Deferred<Int>
fun somethingUsefulTwoAsync() = GlobalScope.async {
doSomethingUsefulTwo()
}
|
// The result type of somethingUsefulOneAsync is Deferred<Int>
func somethingUsefulOneAsync() = GlobalScope.async {
doSomethingUsefulOne()
}
// The result type of somethingUsefulTwoAsync is Deferred<Int>
func somethingUsefulTwoAsync() = GlobalScope.async {
doSomethingUsefulTwo()
}
|
// note that we don't have `runBlocking` to the right of `main` in this example
fun main() {
val time = measureTimeMillis {
// we can initiate async actions outside of a coroutine
val one = somethingUsefulOneAsync()
val two = somethingUsefulTwoAsync()
// but waiting for a result must involve either suspending or blocking.
// here we use `runBlocking { ... }` to block the main thread while waiting for the result
runBlocking {
println("The answer is ${one.await() + two.await()}")
}
}
println("Completed in $time ms")
}
|
// note that we don't have `runBlocking` to the right of `main` in this example
func main() {
let time = measureTimeMillis {
// we can initiate async actions outside of a coroutine
let one = somethingUsefulOneAsync()
let two = somethingUsefulTwoAsync()
// but waiting for a result must involve either suspending or blocking.
// here we use `runBlocking { ... }` to block the main thread while waiting for the result
runBlocking {
print("The answer is ${one.await() + two.await()}")
}
}
print("Completed in $time ms")
}
|
Structured concurrency with async
|
suspend fun concurrentSum(): Int = coroutineScope {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
one.await() + two.await()
}
|
suspend func concurrentSum() -> Int = coroutineScope {
let one = async { doSomethingUsefulOne() }
let two = async { doSomethingUsefulTwo() }
one.await() + two.await()
}
|
val time = measureTimeMillis {
println("The answer is ${concurrentSum()}")
}
println("Completed in $time ms")
|
let time = measureTimeMillis {
print("The answer is ${concurrentSum()}")
}
print("Completed in $time ms")
|
import kotlinx.coroutines.*
fun main() = runBlocking<Unit> {
try {
failedConcurrentSum()
} catch(e: ArithmeticException) {
println("Computation failed with ArithmeticException")
}
}
suspend fun failedConcurrentSum(): Int = coroutineScope {
val one = async<Int> {
try {
delay(Long.MAX_VALUE) // Emulates very long computation
42
} finally {
println("First child was cancelled")
}
}
val two = async<Int> {
println("Second child throws an exception")
throw ArithmeticException()
}
one.await() + two.await()
}
|
import kotlinx.coroutines.*
func main() = runBlocking<Unit> {
try {
failedConcurrentSum()
} catch(e: ArithmeticException) {
print("Computation failed with ArithmeticException")
}
}
suspend func failedConcurrentSum() -> Int = coroutineScope {
let one = async<Int> {
try {
delay(Long.MAX_VALUE) // Emulates very long computation
42
} finally {
print("First child was cancelled")
}
}
let two = async<Int> {
print("Second child throws an exception")
throw ArithmeticException()
}
one.await() + two.await()
}
|